﻿#include "flight.h"
///显示主菜单
void showmenu()
{
	cout << "********************************" << endl;
	cout << "****欢迎使用飞机订票管理系统****" << endl;
	cout << "*********0.退出管理系统*********" << endl;
	cout << "*********1.录入航班信息*********" << endl;
	cout << "*********2.修改航班信息*********" << endl;
	cout << "*********3.总览航班信息*********" << endl;
	cout << "*********4.保存航班信息*********" << endl;
	cout << "*********5.读取航线信息*********" << endl;
	cout << "*********6.查询航线信息*********" << endl;
	cout << "*********7.承办订票服务*********" << endl;
	cout << "*********8.承办退票服务*********" << endl;
	cout << "*******9.查询航班成员名单*******" << endl;
	cout << "********************************" << endl;
}
///头结点设为空
node* phead = NULL;
/**
 * 录入航班信息
 * \param pNewnode:新节点
 * \param phead:头结点
 * 依次输入航班号飞机号，终点站名，起始时间，落地时间，乘员定额，并将这些信息存入节点数据域
 * \return
 */
void Getflight()
{
	node* pNewnode = new node[sizeof(node)];
	pNewnode->pNext = NULL;

	///头插,若头阶段为空，则以新节点为头结点
	if (phead == NULL)
	{
		phead = pNewnode;
	}
	///若头阶段不为空
	else
	{
		pNewnode->pNext = phead;
		phead = pNewnode;
	}
	cout << "请输入航班号：";
	cin >> pNewnode->flight_num;
	cout << "请输入飞机号：";
	cin >> pNewnode->plane_num;
	cout << "请输入终点站名：";
	cin >> pNewnode->finish_place;
	cout << "请输入起始时间(年 月 日)：";
	cin >> pNewnode->start_time;
	cout << "请输入落地时间(年 月 日)：";
	cin >> pNewnode->finish_time;
	cout << "请输入乘员定额：";
	cin >> pNewnode->seatsum;
	cout << "航班信息录入成功！";
	pNewnode->remain_ticket = pNewnode->seatsum;
	///暂停
	system("pause");
	///清屏
	system("cls");
}

/**
 * 修改航班信息
 * \param flight[20]:所需修改航班航班号
 * \param fl:判断是否找到该航班的中间变量，若未找到则为空，反之不为空
 * \return
 */
void Changeflight()
{
	char flight[20];
	cout << "请需要修改的航班的航班号：";
	cin >> flight;//输入目的地

	node* p = phead;
	node* fl = NULL;
	///遍历链表
	while (p != NULL)
	{
		///字符串比较，遍历链表中寻找对应节点
		if (strcmp(p->flight_num, flight) == 0)
		{
			fl = p;
			cout << "飞机号修改为：";
			cin >> p->plane_num;
			cout << "终点站名修改为：";
			cin >> p->finish_place;
			cout << "起始时间修改为：";
			cin >> p->start_time;
			cout << "落地时间修改为：";
			cin >> p->finish_time;
			cout << "乘员定额修改为：";
			int a = p->seatsum;//原成员定额
			cin >> p->seatsum;
			p->remain_ticket = p->remain_ticket + (p->seatsum - a);
			cout << "航班信息修改成功！";
		}
		p = p->pNext;
	}
	if (fl == NULL)
		cout << "未找到需要修改的航班信息...";

	system("pause");//暂停
	system("cls");//清屏

}

/**
 * 总览航班信息
 * \param p:链表节点
 * \return
 * 遍历链表，依次输出链表节点数据域中的内容
 */
void Printflight()
{
	cout << "*" << setw(2) << " " << "航班号" << setw(3) << "*" << setw(2) << " " << "飞机号" << setw(3) << " *" << setw(2) << " " << "终点站名" << setw(3) << " *" << setw(2) << " " << "起始时间" << setw(3) << " *" << setw(2) << " " << "落地时间" << setw(3) << " *" << setw(2) << " " << "乘员定额" << setw(3) << "*" << setw(2) << " " << "剩余票量" << setw(3) << " * " << endl;

	node* p = phead;
	while (p != NULL)//遍历链表
	{
		cout << "*" << setw(9) << p->flight_num << " * " << setw(9) << p->plane_num << "*" << setw(11) << p->finish_place << " * " << setw(10) << p->start_time << " *" << setw(12) << p->finish_time << "* " << setw(10) << p->seatsum << " * " << setw(10) << p->remain_ticket << "*" << endl;
		p = p->pNext;

	}
	system("pause");//暂停
	system("cls");//清屏
}
///保存航班信息
void Saveflight()
{
	///打开文件
	ofstream outfile("flight.dat", ios::out, ios::binary);
	if (!outfile)
	{
		cout << "打开文件失败" << endl;
		system("pause");//暂停
		return;
	}
	node* p = phead;
	///遍历链表
	while (p != NULL) {
		///航班号写入文件
		outfile.write((const char*)&p->flight_num, sizeof(p->flight_num));
		///飞机号写入文件
		outfile.write((const char*)&p->plane_num, sizeof(p->plane_num));
		///终点站名写入文件
		outfile.write((const char*)&p->finish_place, sizeof(p->finish_place));
		///起飞时间写入文件
		outfile.write((const char*)&p->start_time, sizeof(p->start_time));
		///落地时间写入文件
		outfile.write((const char*)&p->finish_time, sizeof(p->finish_time));
		///乘员定额写入文件
		outfile.write((const char*)&p->seatsum, sizeof(p->seatsum));
		///剩余票量写入文件
		outfile.write((const char*)&p->remain_ticket, sizeof(p->remain_ticket));
		///订票人数写入文件
		outfile.write((const char*)&p->num, sizeof(p->num));
		///排队人数写入文件
		outfile.write((const char*)&p->queue_num, sizeof(p->queue_num));
		///乘员信息写入文件，通过循环将每个乘员皆写入
		for (int i = 0; i <= p->num - 1; i++)
			outfile.write((char*)&p->peo[i], sizeof(p->peo[i]));
		///排队候补乘员信息写入文件，通过循环将每个排队候补乘员皆写入
		for (int i = 0; i <= p->queue_num - 1; i++)
			outfile.write((char*)&p->queue[i], sizeof(p->queue[i]));

		p = p->pNext;

	}

	cout << "保存数据成功" << endl;
	///关闭文件
	outfile.close();

	system("pause");//暂停
	system("cls");//清屏

}
///读取航班信息
void Readflight()
{
	///打开文件
	ifstream infile("flight.dat", ios::in, ios::binary);
	if (!infile)
	{
		cout << "打开文件失败" << endl;
		return;
	}

	char flnum[20] = {};
	///读到的航班号不为空时循环，遍历链表，创建新节点
	while (infile.read((char*)&flnum, sizeof(flnum)))
	{
		///创建新节点
		node* pNewnode = new node[sizeof(node)];
		///读到的航班号复制至航班号中
		memcpy(pNewnode->flight_num, flnum, sizeof(flnum));
		///从文件中读取飞机号
		infile.read((char*)&pNewnode->plane_num, sizeof(pNewnode->plane_num));
		///从文件中读取终点站名
		infile.read((char*)&pNewnode->finish_place, sizeof(pNewnode->finish_place));
		///从文件中读取起飞时间
		infile.read((char*)&pNewnode->start_time, sizeof(pNewnode->start_time));
		///从文件中读取落地时间
		infile.read((char*)&pNewnode->finish_time, sizeof(pNewnode->finish_time));
		///从文件中读取乘员定额
		infile.read((char*)&pNewnode->seatsum, sizeof(pNewnode->seatsum));
		///从文件中读取剩余票量
		infile.read((char*)&pNewnode->remain_ticket, sizeof(pNewnode->remain_ticket));
		///从文件中读取订票人数
		infile.read((char*)&pNewnode->num, sizeof(pNewnode->num));
		///从文件中读取排队人数
		infile.read((char*)&pNewnode->queue_num, sizeof(pNewnode->queue_num));
		///从文件中读取乘员信息
		for (int i = 0; i <= pNewnode->num - 1; i++)
			infile.read((char*)&pNewnode->peo[i], sizeof(pNewnode->peo[i]));
		///从文件中读取乘员信息
		for (int i = 0; i <= pNewnode->queue_num - 1; i++)
			infile.read((char*)&pNewnode->queue[i], sizeof(pNewnode->queue[i]));

		pNewnode->pNext = NULL;

		///头插法,插入新节点存储文件数据
		if (phead == NULL)
		{
			phead = pNewnode;
		}
		else
		{
			pNewnode->pNext = phead;
			phead = pNewnode;
		}

	}

	///关闭文件
	infile.close();
	cout << "读取数据成功" << endl;

	system("pause");//暂停
	system("cls");//清屏
}


/**
 * 查询航班信息
 * \param place[20]:所查找航班的目的地信息
 * \return
 */
void Findflight()
{
	char place[20];
	cout << "请输入需要查找航班的目的地：";
	cin >> place;

	node* p = phead;
	node* fl = NULL;
	///遍历链表
	while (p != NULL)
	{
		///所输入目的地与节点中的目的地信息做字符串比较，寻找对应航班
		if (strcmp(p->finish_place, place) == 0)
		{
			if (fl == NULL)
			{
				cout << "对应航班信息如下：" << endl;
				cout << "*" << setw(2) << " " << "航班号" << setw(3) << "*" << setw(2) << " " << "飞机号" << setw(3) << " *" << setw(2) << " " << "终点站名" << setw(3) << " *" << setw(2) << " " << "起始时间" << setw(3) << " *" << setw(2) << " " << "落地时间" << setw(3) << " *" << setw(2) << " " << "乘员定额" << setw(3) << "*" << setw(2) << " " << "剩余票量" << setw(3) << " * " << endl;
			}
			fl = p;
			/// 输出查找到节点航班信息
			cout << "*" << setw(9) << p->flight_num << " * " << setw(9) << p->plane_num << "*" << setw(11) << p->finish_place << " * " << setw(10) << p->start_time << " *" << setw(12) << p->finish_time << "* " << setw(10) << p->seatsum << " * " << setw(10) << p->remain_ticket << "*" << endl;
		}

		p = p->pNext;
	}
	if (fl == NULL)
		cout << "抱歉，未找到对应航班...";
	system("pause");//暂停
	system("cls");//清屏
	///没有找到,返回空指针

}

/**
 * 承办订票服务
 * \param flnum[20]:所订航班的航班号信息
 * \param na[10]:购票者姓名
 * \param id1[20]:购票者身份证号
 * \param num1:购票者购票数
 * \param level[20]:购票者所订航班舱位等级
 * \return
 */
void Buy_ticket()
{
	char na[10]; char id1[20]; int num1 = 0; char level[20]; char flnum[20];
	cout << "请输入所订机票的航班号：";

	///查找所订航班
	cin >> flnum;
	node* p = phead;
	node* fl = NULL;
	///遍历链表
	while (p != NULL)
	{
		///字符串比较，根据航班号寻找对应节点
		if (strcmp(p->flight_num, flnum) == 0)
		{
			fl = p; break;
		}

		p = p->pNext;
	}
	if (fl == NULL)
	{
		cout << "抱歉，未找到对应航班...";
		system("pause");//暂停
		system("cls");//清屏
		return;
	}
	///订票
	while (1)
	{
		cout << "请输入姓名：";
		cin >> na;
		cout << "请输入身份证号：";
		cin >> id1;
		cout << "请输入订票数：";
		cin >> num1;
		cout << "请输入所订的舱位等级(头等舱/商务舱/经济舱)：";
		cin >> level;


		///若余票数少于订票额
		if (p->remain_ticket - num1 < 0)
		{
			cout << endl << "余票数少于订票额,请问是否继续订票?" << endl;
			cout << "若继续订票，将登记排队候补；" << endl;
			cout << "是:1  否:0" << endl;
			cout << "请输入(1/0):";
			char a;
			cin >> a;
			///若取消订票
			if (a == '0')
			{
				cout << "已取消订票";
				system("pause");//暂停
				system("cls");//清屏
				break;
			}
			///若排队候补
			if (a == '1')
			{

				p->queue[p->queue_num] = Get_ticket(p->queue[p->queue_num], na, id1, num1, level);
				p->queue_num++;
				cout << "已完成登记排队候补"; break;
			}
			if (a != '0' && a != '1')
			{
				cout << "输入有误请重试，已取消订票...";
				break;
			}
		}
		///将订票信息存入节点
		p->peo[p->num] = Get_ticket(p->peo[p->num], na, id1, num1, level);
		///订票人数增加
		p->num++;
		///更新剩余票量
		p->remain_ticket = p->remain_ticket - num1;

		cout << endl;
		cout << "是否继续添加乘客？" << endl;
		cout << "是:1  否:0" << endl;
		cout << "请输入(1/0):";
		char a;
		cin >> a;
		if (a == '0')
			break;
		if (a == '1')
			continue;
		if (a != '0' && a != '1')
		{
			cout << "输入有误请重试，已返回至主菜单...";
			break;
		}
	}
	system("pause");//暂停
	system("cls");//清屏
}

/**
 * 承办订票服务
 * \param flnum[20]:所订航班的航班号信息
 * \return
 */
void Return_ticket()
{
	char flnum[20];
	cout << "请输入退订的航班的航班号：";
	///根据航班号查找需要退订的航班
	cin >> flnum;
	node* p = phead;
	node* fl = NULL;
	///查找对应的航班，遍历链表
	while (p != NULL)
	{
		///字符串比较，查找多退订航班
		if (strcmp(p->flight_num, flnum) == 0)
		{
			fl = p; break;
		}

		p = p->pNext;
	}
	///若未找到对应航班
	if (fl == NULL)
	{
		cout << "抱歉，未找到对应航班...";
		system("pause");//暂停
		system("cls");//清屏
		return;
	}

	char  id1[20];
	cout << "请输入退订乘客的身份证号：";
	cin >> id1;

	people a; int i = 0;
	a = Getid(a, id1);
	///根据乘客身份证号查找乘客
	for (; i <= 19; i++)
	{

		if (a == p->peo[i])
		{
			p->remain_ticket = sum_ticket(p->remain_ticket, p->peo[i]);//更新剩余票量
			p->peo[i] = p->peo[i + 1];
			p->num--;
			break;
		}
		else
		{
			cout << "未找到对应乘客...";
			system("pause");//暂停
			system("cls");//清屏
			return;
		}
	}


	///删去退票乘客数据
	for (; i <= 18; i++)
	{
		p->peo[i] = p->peo[i + 1];
		if (i == 18)
			p->peo[i + 1] = { };
	}
	int quenum = 0;
	///根据剩余票数和订票数，使符合条件的排队候补乘客补上
	for (; quenum <= p->queue_num - 1; quenum++)
	{
		if (p->remain_ticket >= p->queue[quenum])
		{
			p->remain_ticket = que_ticket(p->remain_ticket, p->queue[quenum]);
			p->peo[p->num] = p->queue[quenum];

			///删除已成功排队候补的乘客
			for (int b = quenum; b <= 18; b++)
			{
				p->queue[b] = p->queue[b + 1];
				if (i == 18)
					p->queue[b + 1] = { };
			}
			p->queue_num--;
			quenum--;
			p->num++;

		}

	}

	cout << "已成功退票,排队候补已根据情况改变" << endl;
	system("pause");//暂停
	system("cls");//清屏
	return;

}

/**
 * 查询航班成员名单
 * \param flnum[20]:所订航班的航班号信息
 * \return
 */
void Showflightpeople()
{
	cout << "请输入查询航班的航班号：";

	char flnum[20];
	///查找所订航班
	cin >> flnum;
	node* p = phead;
	node* fl = NULL;
	///遍历链表，查找航班
	while (p != NULL)
	{
		///字符串比较，寻找对应航班
		if (strcmp(p->flight_num, flnum) == 0)
		{
			fl = p; break;
		}

		p = p->pNext;
	}
	///若未找到对应航班
	if (fl == NULL)
	{
		cout << "抱歉，未找到对应航班...";
		system("pause");//暂停
		system("cls");//清屏
		return;
	}
	cout << "成功订票乘客如下：" << endl;
	cout << "*" << setw(2) << " " << "姓名" << setw(3) << "*" << setw(6) << " " << "身份证号" << setw(7) << "*" << setw(1) << " " << "订票数" << setw(2) << "*" << setw(1) << " " << "舱位等级" << setw(2) << "*" << endl;
	///输出该航班中乘员信息
	for (int i = 0; i <= p->num - 1; i++)
	{
		Showpeople(p->peo[i]);
	}
	cout << "排队候补乘客如下：" << endl;
	cout << "*" << setw(2) << " " << "姓名" << setw(3) << "*" << setw(6) << " " << "身份证号" << setw(7) << "*" << setw(1) << " " << "订票数" << setw(2) << "*" << setw(1) << " " << "舱位等级" << setw(2) << "*" << endl;
	///输出该航班中候补乘员信息
	for (int i = 0; i <= p->queue_num - 1; i++)
	{
		Showpeople(p->queue[i]);
	}
	system("pause");//暂停
	system("cls");//清屏
}
